﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Numerics;
using System.Text;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// 流扩展类
    /// </summary>
    public static partial class StreamEx
    {
        #region readIQ
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataLength"></param>
        /// <param name="count"></param>
        /// <param name="dataTypeCode"></param>
        /// <param name="iqIndependent">iq数据是否是分开的,IQ数据在不同来源为true,同一来源为false</param>
        /// <returns></returns>
        private static int GetReadIQCount(long dataLength, int count, TypeCode dataTypeCode, bool iqIndependent)
        {
            int eleSize = TypeEx.SizeOf(dataTypeCode);
            long maxCount;
            if (iqIndependent)
            {
                maxCount = dataLength / eleSize;
            }
            else
            {
                maxCount = dataLength / (eleSize * 2);
            }

            if (count > 0 && count <= maxCount)
            {
                return count;
            }
            else
            {
                return (int)maxCount;
            }
        }

        private static void PrimitiveReadIQ(BinaryReader reader, Complex[] destination, int startIndex,
            int readCount, TypeCode dataTypeCode)
        {
            int index = startIndex;
            switch (dataTypeCode)
            {
                case TypeCode.Char:
                    char iDataChar, qDataChar;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataChar = reader.ReadChar();
                        qDataChar = reader.ReadChar();
                        destination[index] = new Complex(iDataChar, qDataChar);
                        index++;
                    }
                    break;
                case TypeCode.Byte:
                    byte iDataByte, qDataByte;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataByte = reader.ReadByte();
                        qDataByte = reader.ReadByte();
                        destination[index] = new Complex(iDataByte, qDataByte);
                        index++;
                    }
                    break;
                case TypeCode.SByte:
                    sbyte iDataSByte, qDataSByte;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataSByte = reader.ReadSByte();
                        qDataSByte = reader.ReadSByte();
                        destination[index] = new Complex(iDataSByte, qDataSByte);
                        index++;
                    }
                    break;
                case TypeCode.Int16:
                    Int16 iDataInt16, qDataInt16;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataInt16 = reader.ReadInt16();
                        qDataInt16 = reader.ReadInt16();
                        destination[index] = new Complex(iDataInt16, qDataInt16);
                        index++;
                    }
                    break;
                case TypeCode.UInt16:
                    UInt16 iDataUInt16, qDataUInt16;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataUInt16 = reader.ReadUInt16();
                        qDataUInt16 = reader.ReadUInt16();
                        destination[index] = new Complex(iDataUInt16, qDataUInt16);
                        index++;
                    }
                    break;
                case TypeCode.Int32:
                    Int32 iDataInt32, qDataInt32;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataInt32 = reader.ReadInt32();
                        qDataInt32 = reader.ReadInt32();
                        destination[index] = new Complex(iDataInt32, qDataInt32);
                        index++;
                    }
                    break;
                case TypeCode.UInt32:
                    UInt32 iDataUInt32, qDataUInt32;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataUInt32 = reader.ReadUInt32();
                        qDataUInt32 = reader.ReadUInt32();
                        destination[index] = new Complex(iDataUInt32, qDataUInt32);
                        index++;
                    }
                    break;
                case TypeCode.Int64:
                    Int64 iDataInt64, qDataInt64;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataInt64 = reader.ReadInt64();
                        qDataInt64 = reader.ReadInt64();
                        destination[index] = new Complex(iDataInt64, qDataInt64);
                        index++;
                    }
                    break;
                case TypeCode.UInt64:
                    UInt64 iDataUInt64, qDataUInt64;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataUInt64 = reader.ReadUInt64();
                        qDataUInt64 = reader.ReadUInt64();
                        destination[index] = new Complex(iDataUInt64, qDataUInt64);
                        index++;
                    }
                    break;
                case TypeCode.Single:
                    float iDataSingle, qDataSingle;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataSingle = reader.ReadSingle();
                        qDataSingle = reader.ReadSingle();
                        destination[index] = new Complex(iDataSingle, qDataSingle);
                        index++;
                    }
                    break;
                case TypeCode.Double:
                    double iDataDouble, qDataDouble;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataDouble = reader.ReadDouble();
                        qDataDouble = reader.ReadDouble();
                        destination[index] = new Complex(iDataDouble, qDataDouble);
                        index++;
                    }
                    break;
                case TypeCode.Decimal:
                    decimal iDataDecimal, qDataDecimal;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataDecimal = reader.ReadDecimal();
                        qDataDecimal = reader.ReadDecimal();
                        destination[index] = new Complex((double)iDataDecimal, (double)qDataDecimal);
                        index++;
                    }
                    break;
                default:
                    throw new NotSupportedException(dataTypeCode.ToString());
            }

        }
        private static void PrimitiveReadIQ(BinaryReader readerI, BinaryReader readerQ, Complex[] destination,
            int startIndex, int readCount, TypeCode dataTypeCode)
        {
            int index = startIndex;
            switch (dataTypeCode)
            {
                case TypeCode.Char:
                    char iDataChar, qDataChar;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataChar = readerI.ReadChar();
                        qDataChar = readerQ.ReadChar();
                        destination[index] = new Complex(iDataChar, qDataChar);
                        index++;
                    }
                    break;
                case TypeCode.Byte:
                    byte iDataByte, qDataByte;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataByte = readerI.ReadByte();
                        qDataByte = readerQ.ReadByte();
                        destination[index] = new Complex(iDataByte, qDataByte);
                        index++;
                    }
                    break;
                case TypeCode.SByte:
                    sbyte iDataSByte, qDataSByte;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataSByte = readerI.ReadSByte();
                        qDataSByte = readerQ.ReadSByte();
                        destination[index] = new Complex(iDataSByte, qDataSByte);
                        index++;
                    }
                    break;
                case TypeCode.Int16:
                    Int16 iDataInt16, qDataInt16;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataInt16 = readerI.ReadInt16();
                        qDataInt16 = readerQ.ReadInt16();
                        destination[index] = new Complex(iDataInt16, qDataInt16);
                        index++;
                    }
                    break;
                case TypeCode.UInt16:
                    UInt16 iDataUInt16, qDataUInt16;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataUInt16 = readerI.ReadUInt16();
                        qDataUInt16 = readerQ.ReadUInt16();
                        destination[index] = new Complex(iDataUInt16, qDataUInt16);
                        index++;
                    }
                    break;
                case TypeCode.Int32:
                    Int32 iDataInt32, qDataInt32;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataInt32 = readerI.ReadInt32();
                        qDataInt32 = readerQ.ReadInt32();
                        destination[index] = new Complex(iDataInt32, qDataInt32);
                        index++;
                    }
                    break;
                case TypeCode.UInt32:
                    UInt32 iDataUInt32, qDataUInt32;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataUInt32 = readerI.ReadUInt32();
                        qDataUInt32 = readerQ.ReadUInt32();
                        destination[index] = new Complex(iDataUInt32, qDataUInt32);
                        index++;
                    }
                    break;
                case TypeCode.Int64:
                    Int64 iDataInt64, qDataInt64;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataInt64 = readerI.ReadInt64();
                        qDataInt64 = readerQ.ReadInt64();
                        destination[index] = new Complex(iDataInt64, qDataInt64);
                        index++;
                    }
                    break;
                case TypeCode.UInt64:
                    UInt64 iDataUInt64, qDataUInt64;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataUInt64 = readerI.ReadUInt64();
                        qDataUInt64 = readerQ.ReadUInt64();
                        destination[index] = new Complex(iDataUInt64, qDataUInt64);
                        index++;
                    }
                    break;
                case TypeCode.Single:
                    float iDataSingle, qDataSingle;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataSingle = readerI.ReadSingle();
                        qDataSingle = readerQ.ReadSingle();
                        destination[index] = new Complex(iDataSingle, qDataSingle);
                        index++;
                    }
                    break;
                case TypeCode.Double:
                    double iDataDouble, qDataDouble;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataDouble = readerI.ReadDouble();
                        qDataDouble = readerQ.ReadDouble();
                        destination[index] = new Complex(iDataDouble, qDataDouble);
                        index++;
                    }
                    break;
                case TypeCode.Decimal:
                    decimal iDataDecimal, qDataDecimal;
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataDecimal = readerI.ReadDecimal();
                        qDataDecimal = readerQ.ReadDecimal();
                        destination[index] = new Complex((double)iDataDecimal, (double)qDataDecimal);
                        index++;
                    }
                    break;
                default:
                    throw new NotSupportedException(dataTypeCode.ToString());
            }

        }

        private static void PrimitiveReadIQ<T>(BinaryReader reader, T[] iDataBuffer, T[] qDataBuffer,
            int startIndex, int readCount, TypeCode dataTypeCode)
        {
            int index = startIndex;
            switch (Type.GetTypeCode(typeof(T)))
            {
                case TypeCode.Char:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var charIBuffer = iDataBuffer as char[];
                        var charQBuffer = qDataBuffer as char[];
                        for (int i = 0; i < readCount; i++)
                        {
                            charIBuffer[index] = reader.ReadChar();
                            charQBuffer[index] = reader.ReadChar();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.Byte:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var byteIBuffer = iDataBuffer as byte[];
                        var byteQBuffer = qDataBuffer as byte[];
                        for (int i = 0; i < readCount; i++)
                        {
                            byteIBuffer[index] = reader.ReadByte();
                            byteQBuffer[index] = reader.ReadByte();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.SByte:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var sByteIBuffer = iDataBuffer as sbyte[];
                        var sByteQBuffer = qDataBuffer as sbyte[];
                        for (int i = 0; i < readCount; i++)
                        {
                            sByteIBuffer[index] = reader.ReadSByte();
                            sByteQBuffer[index] = reader.ReadSByte();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.Int16:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var int16IBuffer = iDataBuffer as Int16[];
                        var int16QBuffer = qDataBuffer as Int16[];
                        for (int i = 0; i < readCount; i++)
                        {
                            int16IBuffer[index] = reader.ReadInt16();
                            int16QBuffer[index] = reader.ReadInt16();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.UInt16:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var uInt16IBuffer = iDataBuffer as UInt16[];
                        var uInt16QBuffer = qDataBuffer as UInt16[];
                        for (int i = 0; i < readCount; i++)
                        {
                            uInt16IBuffer[index] = reader.ReadUInt16();
                            uInt16QBuffer[index] = reader.ReadUInt16();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.Int32:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var int32IBuffer = iDataBuffer as Int32[];
                        var int32QBuffer = qDataBuffer as Int32[];
                        for (int i = 0; i < readCount; i++)
                        {
                            int32IBuffer[index] = reader.ReadInt32();
                            int32QBuffer[index] = reader.ReadInt32();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.UInt32:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var uInt32IBuffer = iDataBuffer as UInt32[];
                        var uInt32QBuffer = qDataBuffer as UInt32[];
                        for (int i = 0; i < readCount; i++)
                        {
                            uInt32IBuffer[index] = reader.ReadUInt32();
                            uInt32QBuffer[index] = reader.ReadUInt32();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.Int64:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var int64IBuffer = iDataBuffer as Int64[];
                        var int64QBuffer = qDataBuffer as Int64[];
                        for (int i = 0; i < readCount; i++)
                        {
                            int64IBuffer[index] = reader.ReadInt64();
                            int64QBuffer[index] = reader.ReadInt64();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.UInt64:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var uInt64IBuffer = iDataBuffer as UInt64[];
                        var uInt64QBuffer = qDataBuffer as UInt64[];
                        for (int i = 0; i < readCount; i++)
                        {
                            uInt64IBuffer[index] = reader.ReadUInt64();
                            uInt64QBuffer[index] = reader.ReadUInt64();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.Single:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var floatIBuffer = iDataBuffer as float[];
                        var floatQBuffer = qDataBuffer as float[];
                        for (int i = 0; i < readCount; i++)
                        {
                            floatIBuffer[index] = reader.ReadSingle();
                            floatQBuffer[index] = reader.ReadSingle();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.Double:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var doubleIBuffer = iDataBuffer as double[];
                        var doubleQBuffer = qDataBuffer as double[];
                        for (int i = 0; i < readCount; i++)
                        {
                            doubleIBuffer[index] = reader.ReadDouble();
                            doubleQBuffer[index] = reader.ReadDouble();
                            index++;
                        }
                        return;
                    }
                    break;
                case TypeCode.Decimal:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var decimalIBuffer = iDataBuffer as decimal[];
                        var decimalQBuffer = qDataBuffer as decimal[];
                        for (int i = 0; i < readCount; i++)
                        {
                            decimalIBuffer[index] = reader.ReadDecimal();
                            decimalQBuffer[index] = reader.ReadDecimal();
                            index++;
                        }
                        return;
                    }
                    break;
                default:
                    throw new NotSupportedException(dataTypeCode.ToString());
            }

            //需要转换数据类型为目标数据
            Type targetType = typeof(T);
            switch (dataTypeCode)
            {
                case TypeCode.Char:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadChar()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadChar()), index);
                        index++;
                    }
                    break;
                case TypeCode.Byte:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadByte()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadByte()), index);
                        index++;
                    }
                    break;
                case TypeCode.SByte:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadSByte()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadSByte()), index);
                        index++;
                    }
                    break;
                case TypeCode.Int16:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadInt16()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadInt16()), index);
                        index++;
                    }
                    break;
                case TypeCode.UInt16:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadUInt16()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadUInt16()), index);
                        index++;
                    }
                    break;
                case TypeCode.Int32:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadInt32()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadInt32()), index);
                        index++;
                    }
                    break;
                case TypeCode.UInt32:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadUInt32()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadUInt32()), index);
                        index++;
                    }
                    break;
                case TypeCode.Int64:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadInt64()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadInt64()), index);
                        index++;
                    }
                    break;
                case TypeCode.UInt64:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadUInt64()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadUInt64()), index);
                        index++;
                    }
                    break;
                case TypeCode.Single:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadSingle()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadSingle()), index);
                        index++;
                    }
                    break;
                case TypeCode.Double:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadDouble()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadDouble()), index);
                        index++;
                    }
                    break;
                case TypeCode.Decimal:
                    for (int i = 0; i < readCount; i++)
                    {
                        iDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadDecimal()), index);
                        qDataBuffer.SetValue(ConvertEx.ConvertToObject(targetType, reader.ReadDecimal()), index);
                        index++;
                    }
                    break;
                default:
                    throw new NotSupportedException(dataTypeCode.ToString());
            }
        }

        private static void PrimitiveReadIQ(BinaryReader readerI, BinaryReader readerQ, Array iDataBuffer,
            Array qDataBuffer, int startIndex, int readCount, TypeCode dataTypeCode)
        {
            int index = startIndex;
            object iData, qData;
            switch (dataTypeCode)
            {
                case TypeCode.Char:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadChar();
                        qData = readerQ.ReadChar();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.Byte:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadByte();
                        qData = readerQ.ReadByte();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.SByte:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadSByte();
                        qData = readerQ.ReadSByte();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.Int16:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadInt16();
                        qData = readerQ.ReadInt16();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.UInt16:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadUInt16();
                        qData = readerQ.ReadUInt16();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.Int32:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadInt32();
                        qData = readerQ.ReadInt32();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.UInt32:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadUInt32();
                        qData = readerQ.ReadUInt32();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.Int64:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadInt64();
                        qData = readerQ.ReadInt64();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.UInt64:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadUInt64();
                        qData = readerQ.ReadUInt64();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.Single:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadSingle();
                        qData = readerQ.ReadSingle();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.Double:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadDouble();
                        qData = readerQ.ReadDouble();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                case TypeCode.Decimal:
                    for (int i = 0; i < readCount; i++)
                    {
                        iData = readerI.ReadDecimal();
                        qData = readerQ.ReadDecimal();
                        iDataBuffer.SetValue(iData, index);
                        qDataBuffer.SetValue(qData, index);
                        index++;
                    }
                    break;
                default:
                    throw new NotSupportedException(dataTypeCode.ToString());
            }

        }



        /// <summary>
        /// 从文件读取IQ数据到Complex数组
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="fileOffset">文件中读取数据起始位置</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static Complex[] ReadIQ(string filePath, long fileOffset = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (string.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("数据文件不存在", filePath);
            }

            using (var fs = File.OpenRead(filePath))
            {
                if (fileOffset > 0)
                {
                    fs.Seek(fileOffset, SeekOrigin.Begin);
                }

                int readCount = GetReadIQCount(fs.Length - fs.Position, count, dataTypeCode, false);
                var buffer = new Complex[readCount];
                var reader = new BinaryReader(fs);
                PrimitiveReadIQ(reader, buffer, 0, readCount, dataTypeCode);
                return buffer;
            }
        }

        /// <summary>
        /// 从文件读取IQ数据到Complex数组,返回实际读取数据点数
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="destination">目标buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="fileOffset">文件中读取数据起始位置</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ(string filePath, Complex[] destination, int startIndex = -1, int count = -1,
            long fileOffset = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (string.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("数据文件不存在", filePath);
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            EnumerableEx.CheckCollectionPartRangePara(destination.Length, ref startIndex, ref count);
            using (var fs = File.OpenRead(filePath))
            {
                if (fileOffset > 0)
                {
                    fs.Seek(fileOffset, SeekOrigin.Begin);
                }

                int readCount = GetReadIQCount(fs.Length - fs.Position, count, dataTypeCode, false);
                var reader = new BinaryReader(fs);
                PrimitiveReadIQ(reader, destination, startIndex, readCount, dataTypeCode);
                return readCount;
            }
        }




        /// <summary>
        /// 从文件读取IQ数据到Complex数组
        /// </summary>
        /// <param name="iDataFilePath">i数据文件路径</param>
        /// <param name="qDataFilePath">q数据文件路径</param>
        /// <param name="fileOffset">文件中读取数据起始位置</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static Complex[] ReadIQ(string iDataFilePath, string qDataFilePath, long fileOffset = -1,
            int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (string.IsNullOrWhiteSpace(iDataFilePath))
            {
                throw new ArgumentNullException(nameof(iDataFilePath));
            }

            if (!File.Exists(iDataFilePath))
            {
                throw new FileNotFoundException("i数据文件不存在", iDataFilePath);
            }

            if (string.IsNullOrWhiteSpace(qDataFilePath))
            {
                throw new ArgumentNullException(nameof(qDataFilePath));
            }

            if (!File.Exists(qDataFilePath))
            {
                throw new FileNotFoundException("i数据文件不存在", qDataFilePath);
            }

            using (var fsI = File.OpenRead(iDataFilePath))
            {
                using (var fsQ = File.OpenRead(qDataFilePath))
                {
                    long minDataLength = fsI.Length < fsQ.Length ? fsI.Length : fsQ.Length;
                    long dataLength = minDataLength;
                    if (fileOffset > 0)
                    {
                        fsI.Seek(fileOffset, SeekOrigin.Begin);
                        fsQ.Seek(fileOffset, SeekOrigin.Begin);
                        dataLength = minDataLength - fileOffset;
                    }

                    int readCount = GetReadIQCount(dataLength, count, dataTypeCode, true);
                    var buffer = new Complex[readCount];
                    var readerI = new BinaryReader(fsI);
                    var readerQ = new BinaryReader(fsQ);
                    PrimitiveReadIQ(readerI, readerQ, buffer, 0, readCount, dataTypeCode);
                    return buffer;
                }
            }
        }

        /// <summary>
        /// 从文件读取IQ数据到Complex数组,返回实际读取数据点数
        /// </summary>
        /// <param name="iDataFilePath">i数据文件路径</param>
        /// <param name="qDataFilePath">q数据文件路径</param>
        /// <param name="destination">目标buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="fileOffset">文件中读取数据起始位置</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ(string iDataFilePath, string qDataFilePath, Complex[] destination, int startIndex = -1,
            int count = -1, long fileOffset = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (string.IsNullOrWhiteSpace(iDataFilePath))
            {
                throw new ArgumentNullException(nameof(iDataFilePath));
            }

            if (!File.Exists(iDataFilePath))
            {
                throw new FileNotFoundException("i数据文件不存在", iDataFilePath);
            }

            if (string.IsNullOrWhiteSpace(qDataFilePath))
            {
                throw new ArgumentNullException(nameof(qDataFilePath));
            }

            if (!File.Exists(qDataFilePath))
            {
                throw new FileNotFoundException("i数据文件不存在", qDataFilePath);
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            EnumerableEx.CheckCollectionPartRangePara(destination.Length, ref startIndex, ref count);

            using (var fsI = File.OpenRead(iDataFilePath))
            {
                using (var fsQ = File.OpenRead(qDataFilePath))
                {
                    long minDataLength = fsI.Length < fsQ.Length ? fsI.Length : fsQ.Length;
                    long dataLength = minDataLength;
                    if (fileOffset > 0)
                    {
                        fsI.Seek(fileOffset, SeekOrigin.Begin);
                        fsQ.Seek(fileOffset, SeekOrigin.Begin);
                        dataLength = minDataLength - fileOffset;
                    }

                    int readCount = GetReadIQCount(dataLength, count, dataTypeCode, true);
                    var readerI = new BinaryReader(fsI);
                    var readerQ = new BinaryReader(fsQ);
                    PrimitiveReadIQ(readerI, readerQ, destination, startIndex, readCount, dataTypeCode);
                    return readCount;
                }
            }
        }





        /// <summary>
        /// 从文件读取IQ数据到数组
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="fileOffset">文件中读取数据起始位置</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static void ReadIQ<T>(string filePath, out T[] iDataBuffer, out T[] qDataBuffer, long fileOffset = -1,
            int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (string.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("数据文件不存在", filePath);
            }

            using (var fs = File.OpenRead(filePath))
            {
                if (fileOffset > 0)
                {
                    fs.Seek(fileOffset, SeekOrigin.Begin);
                }

                int readCount = GetReadIQCount(fs.Length - fs.Position, count, dataTypeCode, false);
                iDataBuffer = new T[readCount];
                qDataBuffer = new T[readCount];

                var reader = new BinaryReader(fs);
                PrimitiveReadIQ(reader, iDataBuffer, qDataBuffer, 0, readCount, dataTypeCode);
            }
        }


        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="startIndex"></param>
        /// <param name="count"></param>
        /// <param name="fileOffset">文件中读取数据起始位置</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(string filePath, T[] iDataBuffer, T[] qDataBuffer, int startIndex = -1,
            int count = -1, long fileOffset = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            int bufferMinLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            EnumerableEx.CheckCollectionPartRangePara(bufferMinLength, ref startIndex, ref count);

            if (string.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("数据文件不存在", filePath);
            }

            using (var fs = File.OpenRead(filePath))
            {
                if (fileOffset > 0)
                {
                    fs.Seek(fileOffset, SeekOrigin.Begin);
                }

                int readCount = GetReadIQCount(fs.Length - fs.Position, count, dataTypeCode, false);
                var reader = new BinaryReader(fs);
                PrimitiveReadIQ(reader, iDataBuffer, qDataBuffer, startIndex, readCount, dataTypeCode);
                return readCount;
            }
        }




        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="iDataFilePath">i数据文件路径</param>
        /// <param name="qDataFilePath">q数据文件路径</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="fileOffset">文件中读取数据起始位置</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(string iDataFilePath, string qDataFilePath, out T[] iDataBuffer, out T[] qDataBuffer,
            long fileOffset = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (string.IsNullOrWhiteSpace(iDataFilePath))
            {
                throw new ArgumentNullException(nameof(iDataFilePath));
            }

            if (!File.Exists(iDataFilePath))
            {
                throw new FileNotFoundException("i数据文件不存在", iDataFilePath);
            }

            if (string.IsNullOrWhiteSpace(qDataFilePath))
            {
                throw new ArgumentNullException(nameof(qDataFilePath));
            }

            if (!File.Exists(qDataFilePath))
            {
                throw new FileNotFoundException("i数据文件不存在", qDataFilePath);
            }

            using (var fsI = File.OpenRead(iDataFilePath))
            {
                using (var fsQ = File.OpenRead(qDataFilePath))
                {
                    long minDataLength = fsI.Length < fsQ.Length ? fsI.Length : fsQ.Length;
                    long dataLength = minDataLength;
                    if (fileOffset > 0)
                    {
                        fsI.Seek(fileOffset, SeekOrigin.Begin);
                        fsQ.Seek(fileOffset, SeekOrigin.Begin);
                        dataLength = minDataLength - fileOffset;
                    }

                    int readCount = GetReadIQCount(dataLength, count, dataTypeCode, true);
                    var readerI = new BinaryReader(fsI);
                    var readerQ = new BinaryReader(fsQ);
                    iDataBuffer = new T[readCount];
                    qDataBuffer = new T[readCount];
                    PrimitiveReadIQ(readerI, readerQ, iDataBuffer, qDataBuffer, 0, readCount, dataTypeCode);
                    return readCount;
                }
            }
        }

        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="iDataFilePath">i数据文件路径</param>
        /// <param name="qDataFilePath">q数据文件路径</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="fileOffset">文件中读取数据起始位置</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(string iDataFilePath, string qDataFilePath, T[] iDataBuffer, T[] qDataBuffer,
            int startIndex = -1, int count = -1, long fileOffset = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (string.IsNullOrWhiteSpace(iDataFilePath))
            {
                throw new ArgumentNullException(nameof(iDataFilePath));
            }

            if (!File.Exists(iDataFilePath))
            {
                throw new FileNotFoundException("i数据文件不存在", iDataFilePath);
            }

            if (string.IsNullOrWhiteSpace(qDataFilePath))
            {
                throw new ArgumentNullException(nameof(qDataFilePath));
            }

            if (!File.Exists(qDataFilePath))
            {
                throw new FileNotFoundException("i数据文件不存在", qDataFilePath);
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            int maxLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            EnumerableEx.CheckCollectionPartRangePara(maxLength, ref startIndex, ref count);

            using (var fsI = File.OpenRead(iDataFilePath))
            {
                using (var fsQ = File.OpenRead(qDataFilePath))
                {
                    long minDataLength = fsI.Length < fsQ.Length ? fsI.Length : fsQ.Length;
                    long dataLength = minDataLength;
                    if (fileOffset > 0)
                    {
                        fsI.Seek(fileOffset, SeekOrigin.Begin);
                        fsQ.Seek(fileOffset, SeekOrigin.Begin);
                        dataLength = minDataLength - fileOffset;
                    }

                    int readCount = GetReadIQCount(dataLength, count, dataTypeCode, true);
                    var readerI = new BinaryReader(fsI);
                    var readerQ = new BinaryReader(fsQ);
                    PrimitiveReadIQ(readerI, readerQ, iDataBuffer, qDataBuffer, startIndex, readCount, dataTypeCode);
                    return readCount;
                }
            }
        }



        //-----------------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 从文件读取IQ数据到Complex数组
        /// </summary>
        /// <param name="stream">数据流</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static Complex[] ReadIQ(Stream stream, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(stream));
            }

            int readCount = GetReadIQCount(stream.Length - stream.Position, count, dataTypeCode, false);
            var buffer = new Complex[readCount];
            var reader = new BinaryReader(stream);
            PrimitiveReadIQ(reader, buffer, 0, readCount, dataTypeCode);
            return buffer;
        }

        /// <summary>
        /// 从文件读取IQ数据到Complex数组,返回实际读取数据点数
        /// </summary>
        /// <param name="stream">数据流</param>
        /// <param name="destination">目标buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ(Stream stream, Complex[] destination, int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(stream));
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            EnumerableEx.CheckCollectionPartRangePara(destination.Length, ref startIndex, ref count);
            int readCount = GetReadIQCount(stream.Length - stream.Position, count, dataTypeCode, false);
            var reader = new BinaryReader(stream);
            PrimitiveReadIQ(reader, destination, startIndex, readCount, dataTypeCode);
            return readCount;
        }




        /// <summary>
        /// 从文件读取IQ数据到Complex数组
        /// </summary>
        /// <param name="iDataStream">i数据流</param>
        /// <param name="qDataStream">q数据流</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static Complex[] ReadIQ(Stream iDataStream, Stream qDataStream, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (iDataStream == null)
            {
                throw new ArgumentNullException(nameof(iDataStream));
            }

            if (!iDataStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(iDataStream));
            }

            if (qDataStream == null)
            {
                throw new ArgumentNullException(nameof(qDataStream));
            }

            if (!qDataStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(qDataStream));
            }

            long iDataLength = iDataStream.Length - iDataStream.Position;
            long qDataLength = qDataStream.Length - qDataStream.Position;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;
            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            var buffer = new Complex[readCount];
            var readerI = new BinaryReader(iDataStream);
            var readerQ = new BinaryReader(qDataStream);
            PrimitiveReadIQ(readerI, readerQ, buffer, 0, readCount, dataTypeCode);
            return buffer;
        }

        /// <summary>
        /// 从文件读取IQ数据到Complex数组,返回实际读取数据点数
        /// </summary>
        /// <param name="iDataStream">i数据流</param>
        /// <param name="qDataStream">q数据流</param>
        /// <param name="destination">目标buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ(Stream iDataStream, Stream qDataStream, Complex[] destination, int startIndex = -1,
            int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (iDataStream == null)
            {
                throw new ArgumentNullException(nameof(iDataStream));
            }

            if (!iDataStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(iDataStream));
            }

            if (qDataStream == null)
            {
                throw new ArgumentNullException(nameof(qDataStream));
            }

            if (!qDataStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(qDataStream));
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            EnumerableEx.CheckCollectionPartRangePara(destination.Length, ref startIndex, ref count);
            long iDataLength = iDataStream.Length - iDataStream.Position;
            long qDataLength = qDataStream.Length - qDataStream.Position;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;
            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            var readerI = new BinaryReader(iDataStream);
            var readerQ = new BinaryReader(qDataStream);
            PrimitiveReadIQ(readerI, readerQ, destination, startIndex, readCount, dataTypeCode);
            return readCount;
        }





        /// <summary>
        /// 从文件读取IQ数据到数组
        /// </summary>
        /// <param name="stream">数据流</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static void ReadIQ<T>(Stream stream, out T[] iDataBuffer, out T[] qDataBuffer, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(stream));
            }

            int readCount = GetReadIQCount(stream.Length - stream.Position, count, dataTypeCode, false);
            iDataBuffer = new T[readCount];
            qDataBuffer = new T[readCount];

            var reader = new BinaryReader(stream);
            PrimitiveReadIQ(reader, iDataBuffer, qDataBuffer, 0, readCount, dataTypeCode);
        }


        /// <summary>
        /// 从文件读取IQ数据到x数组,返回实际读取数据点数
        /// </summary>
        /// <param name="stream">数据流</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="startIndex"></param>
        /// <param name="count"></param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(Stream stream, T[] iDataBuffer, T[] qDataBuffer, int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(stream));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            int bufferMinLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            EnumerableEx.CheckCollectionPartRangePara(bufferMinLength, ref startIndex, ref count);
            int readCount = GetReadIQCount(stream.Length - stream.Position, count, dataTypeCode, false);
            var reader = new BinaryReader(stream);
            PrimitiveReadIQ(reader, iDataBuffer, qDataBuffer, startIndex, readCount, dataTypeCode);
            return readCount;
        }




        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="iDataStream">i数据流</param>
        /// <param name="qDataStream">q数据流</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(Stream iDataStream, Stream qDataStream, out T[] iDataBuffer, out T[] qDataBuffer, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (iDataStream == null)
            {
                throw new ArgumentNullException(nameof(iDataStream));
            }

            if (!iDataStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(iDataStream));
            }

            if (qDataStream == null)
            {
                throw new ArgumentNullException(nameof(qDataStream));
            }

            if (!qDataStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(qDataStream));
            }

            long iDataLength = iDataStream.Length - iDataStream.Position;
            long qDataLength = qDataStream.Length - qDataStream.Position;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;
            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            var readerI = new BinaryReader(iDataStream);
            var readerQ = new BinaryReader(qDataStream);
            iDataBuffer = new T[readCount];
            qDataBuffer = new T[readCount];
            PrimitiveReadIQ(readerI, readerQ, iDataBuffer, qDataBuffer, 0, readCount, dataTypeCode);
            return readCount;
        }

        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="iDataStream">i数据流</param>
        /// <param name="qDataStream">q数据流</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(Stream iDataStream, Stream qDataStream, T[] iDataBuffer, T[] qDataBuffer,
            int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (iDataStream == null)
            {
                throw new ArgumentNullException(nameof(iDataStream));
            }

            if (!iDataStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(iDataStream));
            }

            if (qDataStream == null)
            {
                throw new ArgumentNullException(nameof(qDataStream));
            }

            if (!qDataStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(qDataStream));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            int maxLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            EnumerableEx.CheckCollectionPartRangePara(maxLength, ref startIndex, ref count);
            long iDataLength = iDataStream.Length - iDataStream.Position;
            long qDataLength = qDataStream.Length - qDataStream.Position;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;
            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            var readerI = new BinaryReader(iDataStream);
            var readerQ = new BinaryReader(qDataStream);
            PrimitiveReadIQ(readerI, readerQ, iDataBuffer, qDataBuffer, startIndex, readCount, dataTypeCode);
            return readCount;
        }

        //-----------------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 从文件读取IQ数据到Complex数组
        /// </summary>
        /// <param name="reader">BinaryReader</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static Complex[] ReadIQ(BinaryReader reader, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            if (!reader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(reader));
            }

            int readCount = GetReadIQCount(reader.BaseStream.Length - reader.BaseStream.Position, count, dataTypeCode, false);
            var buffer = new Complex[readCount];
            PrimitiveReadIQ(reader, buffer, 0, readCount, dataTypeCode);
            return buffer;
        }

        /// <summary>
        /// 从文件读取IQ数据到Complex数组,返回实际读取数据点数
        /// </summary>
        /// <param name="reader">BinaryReader</param>
        /// <param name="destination">目标buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ(BinaryReader reader, Complex[] destination, int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            if (!reader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(reader));
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            EnumerableEx.CheckCollectionPartRangePara(destination.Length, ref startIndex, ref count);
            int readCount = GetReadIQCount(reader.BaseStream.Length - reader.BaseStream.Position, count, dataTypeCode, false);
            PrimitiveReadIQ(reader, destination, startIndex, readCount, dataTypeCode);
            return readCount;
        }




        /// <summary>
        /// 从文件读取IQ数据到Complex数组
        /// </summary>
        /// <param name="iDataReader">i数据BinaryReader</param>
        /// <param name="qDataReader">q数据BinaryReader</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static Complex[] ReadIQ(BinaryReader iDataReader, BinaryReader qDataReader, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (iDataReader == null)
            {
                throw new ArgumentNullException(nameof(iDataReader));
            }

            if (!iDataReader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(iDataReader));
            }

            if (qDataReader == null)
            {
                throw new ArgumentNullException(nameof(qDataReader));
            }

            if (!qDataReader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(qDataReader));
            }

            long iDataLength = iDataReader.BaseStream.Length - iDataReader.BaseStream.Position;
            long qDataLength = qDataReader.BaseStream.Length - qDataReader.BaseStream.Position;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;
            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            var buffer = new Complex[readCount];
            PrimitiveReadIQ(iDataReader, qDataReader, buffer, 0, readCount, dataTypeCode);
            return buffer;
        }

        /// <summary>
        /// 从文件读取IQ数据到Complex数组,返回实际读取数据点数
        /// </summary>
        /// <param name="iDataReader">i数据BinaryReader</param>
        /// <param name="qDataReader">q数据BinaryReader</param>
        /// <param name="destination">目标buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ(BinaryReader iDataReader, BinaryReader qDataReader, Complex[] destination, int startIndex = -1,
            int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (iDataReader == null)
            {
                throw new ArgumentNullException(nameof(iDataReader));
            }

            if (!iDataReader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(iDataReader));
            }

            if (qDataReader == null)
            {
                throw new ArgumentNullException(nameof(qDataReader));
            }

            if (!qDataReader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(qDataReader));
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            EnumerableEx.CheckCollectionPartRangePara(destination.Length, ref startIndex, ref count);
            long iDataLength = iDataReader.BaseStream.Length - iDataReader.BaseStream.Position;
            long qDataLength = qDataReader.BaseStream.Length - qDataReader.BaseStream.Position;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;

            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            PrimitiveReadIQ(iDataReader, qDataReader, destination, startIndex, readCount, dataTypeCode);
            return readCount;
        }





        /// <summary>
        /// 从文件读取IQ数据到数组
        /// </summary>
        /// <param name="reader">数据BinaryReader</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static void ReadIQ<T>(BinaryReader reader, out T[] iDataBuffer, out T[] qDataBuffer, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            if (!reader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(reader));
            }

            int readCount = GetReadIQCount(reader.BaseStream.Length - reader.BaseStream.Position, count, dataTypeCode, false);
            iDataBuffer = new T[readCount];
            qDataBuffer = new T[readCount];

            PrimitiveReadIQ(reader, iDataBuffer, qDataBuffer, 0, readCount, dataTypeCode);
        }


        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="reader">数据BinaryReader</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="startIndex"></param>
        /// <param name="count"></param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(BinaryReader reader, T[] iDataBuffer, T[] qDataBuffer, int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            if (!reader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(reader));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            int bufferMinLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            EnumerableEx.CheckCollectionPartRangePara(bufferMinLength, ref startIndex, ref count);
            int readCount = GetReadIQCount(reader.BaseStream.Length - reader.BaseStream.Position, count, dataTypeCode, false);
            PrimitiveReadIQ(reader, iDataBuffer, qDataBuffer, startIndex, readCount, dataTypeCode);
            return readCount;
        }




        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="iDataReader">i数据BinaryReader</param>
        /// <param name="qDataReader">q数据BinaryReader</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(BinaryReader iDataReader, BinaryReader qDataReader, out T[] iDataBuffer, out T[] qDataBuffer, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (iDataReader == null)
            {
                throw new ArgumentNullException(nameof(iDataReader));
            }

            if (!iDataReader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(iDataReader));
            }

            if (qDataReader == null)
            {
                throw new ArgumentNullException(nameof(qDataReader));
            }

            if (!qDataReader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(qDataReader));
            }

            long iDataLength = iDataReader.BaseStream.Length - iDataReader.BaseStream.Position;
            long qDataLength = qDataReader.BaseStream.Length - qDataReader.BaseStream.Position;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;
            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            iDataBuffer = new T[readCount];
            qDataBuffer = new T[readCount];
            PrimitiveReadIQ(iDataReader, qDataReader, iDataBuffer, qDataBuffer, 0, readCount, dataTypeCode);
            return readCount;
        }

        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="iDataReader">i数据BinaryReader</param>
        /// <param name="qDataReader">q数据BinaryReader</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(BinaryReader iDataReader, BinaryReader qDataReader, T[] iDataBuffer, T[] qDataBuffer,
            int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (iDataReader == null)
            {
                throw new ArgumentNullException(nameof(iDataReader));
            }

            if (!iDataReader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(iDataReader));
            }

            if (qDataReader == null)
            {
                throw new ArgumentNullException(nameof(qDataReader));
            }

            if (!qDataReader.BaseStream.CanRead)
            {
                throw new ArgumentException("数据流不可读", nameof(qDataReader));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            int maxLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            EnumerableEx.CheckCollectionPartRangePara(maxLength, ref startIndex, ref count);

            long iDataLength = iDataReader.BaseStream.Length - iDataReader.BaseStream.Position;
            long qDataLength = qDataReader.BaseStream.Length - qDataReader.BaseStream.Position;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;

            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            PrimitiveReadIQ(iDataReader, qDataReader, iDataBuffer, qDataBuffer, startIndex, readCount, dataTypeCode);
            return readCount;
        }


        //-----------------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 从文件读取IQ数据到Complex数组
        /// </summary>
        /// <param name="buffer">数据buffer</param>
        /// <param name="bufferStartIndex">数据buffer中的起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static Complex[] ReadIQ(byte[] buffer, int bufferStartIndex, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            int readCount = GetReadIQCount(buffer.Length - bufferStartIndex, count, dataTypeCode, false);
            var iqBuffer = new Complex[readCount];
            using (var ms = new MemoryStream(buffer, bufferStartIndex, buffer.Length - bufferStartIndex))
            {
                var reader = new BinaryReader(ms);
                PrimitiveReadIQ(reader, iqBuffer, 0, readCount, dataTypeCode);
            }
            return iqBuffer;
        }

        /// <summary>
        /// 从文件读取IQ数据到Complex数组,返回实际读取数据点数
        /// </summary>
        /// <param name="buffer">数据buffer</param>
        /// <param name="bufferStartIndex">数据buffer中的起始索引</param>
        /// <param name="destination">目标buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ(byte[] buffer, int bufferStartIndex, Complex[] destination, int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            EnumerableEx.CheckCollectionPartRangePara(destination.Length, ref startIndex, ref count);
            int readCount = GetReadIQCount(buffer.Length, count, dataTypeCode, false);
            using (var ms = new MemoryStream(buffer, bufferStartIndex, buffer.Length - bufferStartIndex))
            {
                var reader = new BinaryReader(ms);
                PrimitiveReadIQ(reader, destination, startIndex, readCount, dataTypeCode);
            }
            return readCount;
        }




        /// <summary>
        /// 从文件读取IQ数据到Complex数组
        /// </summary>
        /// <param name="bufferI">i数据buffer</param>
        /// <param name="bufferQ">q数据buffer</param>
        /// <param name="bufferStartIndex">数据buffer中的起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static Complex[] ReadIQ(byte[] bufferI, byte[] bufferQ, int bufferStartIndex, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (bufferI == null)
            {
                throw new ArgumentNullException(nameof(bufferI));
            }

            if (bufferQ == null)
            {
                throw new ArgumentNullException(nameof(bufferQ));
            }

            long iDataLength = bufferI.Length - bufferStartIndex;
            long qDataLength = bufferQ.Length - bufferStartIndex;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;
            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            var buffer = new Complex[readCount];
            using (var msI = new MemoryStream(bufferI, bufferStartIndex, bufferI.Length - bufferStartIndex))
            {
                using (var msQ = new MemoryStream(bufferQ, bufferStartIndex, bufferQ.Length - bufferStartIndex))
                {
                    var iDataReader = new BinaryReader(msI);
                    var qDataReader = new BinaryReader(msQ);
                    PrimitiveReadIQ(iDataReader, qDataReader, buffer, 0, readCount, dataTypeCode);
                }
            }
            return buffer;
        }

        /// <summary>
        /// 从文件读取IQ数据到Complex数组,返回实际读取数据点数
        /// </summary>
        /// <param name="bufferI">i数据buffer</param>
        /// <param name="bufferQ">q数据buffer</param>
        /// <param name="bufferStartIndex">数据buffer中的起始索引</param>
        /// <param name="destination">目标buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ(byte[] bufferI, byte[] bufferQ, int bufferStartIndex, Complex[] destination, int startIndex = -1,
            int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (bufferI == null)
            {
                throw new ArgumentNullException(nameof(bufferI));
            }

            if (bufferQ == null)
            {
                throw new ArgumentNullException(nameof(bufferQ));
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            EnumerableEx.CheckCollectionPartRangePara(destination.Length, ref startIndex, ref count);
            long iDataLength = bufferI.Length - bufferStartIndex;
            long qDataLength = bufferQ.Length - bufferStartIndex;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;

            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            using (var msI = new MemoryStream(bufferI, bufferStartIndex, bufferI.Length - bufferStartIndex))
            {
                using (var msQ = new MemoryStream(bufferQ, bufferStartIndex, bufferQ.Length - bufferStartIndex))
                {
                    var iDataReader = new BinaryReader(msI);
                    var qDataReader = new BinaryReader(msQ);
                    PrimitiveReadIQ(iDataReader, qDataReader, destination, startIndex, readCount, dataTypeCode);
                }
            }
            return readCount;
        }





        /// <summary>
        /// 从文件读取IQ数据到数组
        /// </summary>
        /// <param name="buffer">数据buffer</param>
        /// <param name="bufferStartIndex">数据buffer中的起始索引</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>Complex数组</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static void ReadIQ<T>(byte[] buffer, int bufferStartIndex, out T[] iDataBuffer, out T[] qDataBuffer, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            int readCount = GetReadIQCount(buffer.Length - bufferStartIndex, count, dataTypeCode, false);
            iDataBuffer = new T[readCount];
            qDataBuffer = new T[readCount];
            using (var ms = new MemoryStream(buffer, bufferStartIndex, buffer.Length - bufferStartIndex))
            {
                var reader = new BinaryReader(ms);
                PrimitiveReadIQ(reader, iDataBuffer, qDataBuffer, 0, readCount, dataTypeCode);
            }
        }


        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="buffer">数据buffer</param>
        /// <param name="bufferStartIndex">数据buffer中的起始索引</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="startIndex"></param>
        /// <param name="count"></param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(byte[] buffer, int bufferStartIndex, T[] iDataBuffer, T[] qDataBuffer, int startIndex = -1,
            int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            int bufferMinLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            EnumerableEx.CheckCollectionPartRangePara(bufferMinLength, ref startIndex, ref count);
            int readCount = GetReadIQCount(buffer.Length - bufferStartIndex, count, dataTypeCode, false);
            using (var ms = new MemoryStream(buffer, bufferStartIndex, buffer.Length - bufferStartIndex))
            {
                var reader = new BinaryReader(ms);
                PrimitiveReadIQ(reader, iDataBuffer, qDataBuffer, startIndex, readCount, dataTypeCode);
            }
            return readCount;
        }




        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="bufferI">i数据buffer</param>
        /// <param name="bufferQ">q数据buffer</param>
        /// <param name="bufferStartIndex">数据buffer中的起始索引</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(byte[] bufferI, byte[] bufferQ, int bufferStartIndex, out T[] iDataBuffer, out T[] qDataBuffer, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (bufferI == null)
            {
                throw new ArgumentNullException(nameof(bufferI));
            }

            if (bufferQ == null)
            {
                throw new ArgumentNullException(nameof(bufferQ));
            }


            long iDataLength = bufferI.Length - bufferStartIndex;
            long qDataLength = bufferQ.Length - bufferStartIndex;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;
            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            iDataBuffer = new T[readCount];
            qDataBuffer = new T[readCount];
            using (var msI = new MemoryStream(bufferI, bufferStartIndex, bufferI.Length - bufferStartIndex))
            {
                using (var msQ = new MemoryStream(bufferQ, bufferStartIndex, bufferQ.Length - bufferStartIndex))
                {
                    var iDataReader = new BinaryReader(msI);
                    var qDataReader = new BinaryReader(msQ);
                    PrimitiveReadIQ(iDataReader, qDataReader, iDataBuffer, qDataBuffer, 0, readCount, dataTypeCode);
                }
            }
            return readCount;
        }

        /// <summary>
        /// 从文件读取IQ数据到数组,返回实际读取数据点数
        /// </summary>
        /// <param name="bufferI">i数据buffer</param>
        /// <param name="bufferQ">q数据buffer</param>
        /// <param name="bufferStartIndex">数据buffer中的起始索引</param>
        /// <param name="iDataBuffer">读取到的i数据buffer</param>
        /// <param name="qDataBuffer">读取到的q数据buffer</param>
        /// <param name="startIndex">目标buffer起始索引</param>
        /// <param name="count">读取元素个数,小于0表示读取到结尾</param>
        /// <param name="dataTypeCode">IQ数据类型</param>
        /// <returns>实际读取数据点数</returns>
        /// <exception cref="ArgumentNullException">参数为null异常</exception>
        /// <exception cref="FileNotFoundException">数据文件不存在异常</exception>
        /// <exception cref="ArgumentOutOfRangeException">数据超出范围异常</exception>
        public static int ReadIQ<T>(byte[] bufferI, byte[] bufferQ, int bufferStartIndex, T[] iDataBuffer, T[] qDataBuffer,
            int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (bufferI == null)
            {
                throw new ArgumentNullException(nameof(bufferI));
            }

            if (bufferQ == null)
            {
                throw new ArgumentNullException(nameof(bufferQ));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            int maxLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            EnumerableEx.CheckCollectionPartRangePara(maxLength, ref startIndex, ref count);

            long iDataLength = bufferI.Length - bufferStartIndex;
            long qDataLength = bufferQ.Length - bufferStartIndex;
            long minDataLength = iDataLength < qDataLength ? iDataLength : qDataLength;

            int readCount = GetReadIQCount(minDataLength, count, dataTypeCode, true);
            using (var msI = new MemoryStream(bufferI, bufferStartIndex, bufferI.Length - bufferStartIndex))
            {
                using (var msQ = new MemoryStream(bufferQ, bufferStartIndex, bufferQ.Length - bufferStartIndex))
                {
                    var iDataReader = new BinaryReader(msI);
                    var qDataReader = new BinaryReader(msQ);
                    PrimitiveReadIQ(iDataReader, qDataReader, iDataBuffer, qDataBuffer, startIndex, readCount, dataTypeCode);
                }
            }
            return readCount;
        }


        #endregion


        #region WriteIQ

        private static void PrimitiveWriteIQ<T>(BinaryWriter writer, T[] iDataBuffer, T[] qDataBuffer,
            int startIndex, int count, TypeCode dataTypeCode)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            int maxLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            int endIndex = EnumerableEx.CheckCollectionPartRangePara(maxLength, ref startIndex, ref count);

            switch (Type.GetTypeCode(typeof(T)))
            {
                case TypeCode.Char:
                    if (dataTypeCode == TypeCode.Char)
                    {
                        var charIBuffer = iDataBuffer as char[];
                        var charQBuffer = qDataBuffer as char[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(charIBuffer[i]);
                            writer.Write(charQBuffer[i]);
                        }

                        return;
                    }
                    break;
                case TypeCode.Byte:
                    if (dataTypeCode == TypeCode.Byte)
                    {
                        var byteIBuffer = iDataBuffer as byte[];
                        var byteQBuffer = qDataBuffer as byte[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(byteIBuffer[i]);
                            writer.Write(byteQBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.SByte:
                    if (dataTypeCode == TypeCode.SByte)
                    {
                        var sByteIBuffer = iDataBuffer as sbyte[];
                        var sByteQBuffer = qDataBuffer as sbyte[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(sByteIBuffer[i]);
                            writer.Write(sByteQBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.Int16:
                    if (dataTypeCode == TypeCode.Int16)
                    {
                        var int16IBuffer = iDataBuffer as Int16[];
                        var int16QBuffer = qDataBuffer as Int16[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(int16IBuffer[i]);
                            writer.Write(int16QBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.UInt16:
                    if (dataTypeCode == TypeCode.UInt16)
                    {
                        var uInt16IBuffer = iDataBuffer as UInt16[];
                        var uInt16QBuffer = qDataBuffer as UInt16[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(uInt16IBuffer[i]);
                            writer.Write(uInt16QBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.Int32:
                    if (dataTypeCode == TypeCode.Int32)
                    {
                        var int32IBuffer = iDataBuffer as Int32[];
                        var int32QBuffer = qDataBuffer as Int32[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(int32IBuffer[i]);
                            writer.Write(int32QBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.UInt32:
                    if (dataTypeCode == TypeCode.UInt32)
                    {
                        var uInt32IBuffer = iDataBuffer as UInt32[];
                        var uInt32QBuffer = qDataBuffer as UInt32[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(uInt32IBuffer[i]);
                            writer.Write(uInt32QBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.Int64:
                    if (dataTypeCode == TypeCode.Int64)
                    {
                        var int64IBuffer = iDataBuffer as Int64[];
                        var int64QBuffer = qDataBuffer as Int64[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(int64IBuffer[i]);
                            writer.Write(int64QBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.UInt64:
                    if (dataTypeCode == TypeCode.UInt64)
                    {
                        var uInt64IBuffer = iDataBuffer as UInt64[];
                        var uInt64QBuffer = qDataBuffer as UInt64[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(uInt64IBuffer[i]);
                            writer.Write(uInt64QBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.Single:
                    if (dataTypeCode == TypeCode.Single)
                    {
                        var floatIBuffer = iDataBuffer as float[];
                        var floatQBuffer = qDataBuffer as float[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(floatIBuffer[i]);
                            writer.Write(floatQBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.Double:
                    if (dataTypeCode == TypeCode.Double)
                    {
                        var doubleIBuffer = iDataBuffer as double[];
                        var doubleQBuffer = qDataBuffer as double[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(doubleIBuffer[i]);
                            writer.Write(doubleQBuffer[i]);
                        }
                        return;
                    }
                    break;
                case TypeCode.Decimal:
                    if (dataTypeCode == TypeCode.Decimal)
                    {
                        var decimalIBuffer = iDataBuffer as decimal[];
                        var decimalQBuffer = qDataBuffer as decimal[];
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            writer.Write(decimalIBuffer[i]);
                            writer.Write(decimalQBuffer[i]);
                        }
                        return;
                    }
                    break;
                default:
                    throw new NotImplementedException($"未实现的目标数据类型{dataTypeCode.ToString()}");
            }

            //需要转换数据类型为目标数据
            switch (dataTypeCode)
            {
                case TypeCode.Char:

                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToChar(iDataBuffer[i]));
                        writer.Write(Convert.ToChar(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.Byte:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToByte(iDataBuffer[i]));
                        writer.Write(Convert.ToByte(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.SByte:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToSByte(iDataBuffer[i]));
                        writer.Write(Convert.ToSByte(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.Int16:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToInt16(iDataBuffer[i]));
                        writer.Write(Convert.ToInt16(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.UInt16:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToUInt16(iDataBuffer[i]));
                        writer.Write(Convert.ToUInt16(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.Int32:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToInt32(iDataBuffer[i]));
                        writer.Write(Convert.ToInt32(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.UInt32:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToUInt32(iDataBuffer[i]));
                        writer.Write(Convert.ToUInt32(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.Int64:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToInt64(iDataBuffer[i]));
                        writer.Write(Convert.ToInt64(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.UInt64:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToUInt64(iDataBuffer[i]));
                        writer.Write(Convert.ToUInt64(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.Single:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToSingle(iDataBuffer[i]));
                        writer.Write(Convert.ToSingle(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.Double:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToDouble(iDataBuffer[i]));
                        writer.Write(Convert.ToDouble(qDataBuffer[i]));
                    }
                    break;
                case TypeCode.Decimal:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write(Convert.ToDecimal(iDataBuffer[i]));
                        writer.Write(Convert.ToDecimal(qDataBuffer[i]));
                    }
                    break;
                default:
                    throw new NotImplementedException($"未实现的目标数据类型{dataTypeCode.ToString()}");
            }
        }

        /// <summary>
        /// 将IQ数据写到文件
        /// </summary>
        /// <typeparam name="T">要写入的数据类型</typeparam>
        /// <param name="filePath">要写入的文件路径</param>
        /// <param name="iDataBuffer">I数据buffer</param>
        /// <param name="qDataBuffer">Q数据buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="fileMode">文件打开操作模式</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型,为null时与buffer数据类型一致</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        public static void WriteIQ<T>(string filePath, T[] iDataBuffer, T[] qDataBuffer, int startIndex = -1, int count = -1,
            FileMode fileMode = FileMode.CreateNew, TypeCode? dataTypeCode = null)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (string.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentNullException(nameof(filePath));
            }
            else
            {
                DirectoryInfoEx.CheckFilePathDirectory(filePath);
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }


            using (var fs = new FileStream(filePath, fileMode, FileAccess.Write))
            {
                var writer = new BinaryWriter(fs);
                if (!dataTypeCode.HasValue)
                {
                    dataTypeCode = Type.GetTypeCode(typeof(T));
                }

                PrimitiveWriteIQ<T>(writer, iDataBuffer, qDataBuffer, startIndex, count, dataTypeCode.Value);
            }
        }

        /// <summary>
        /// 将IQ数据写到Stream
        /// </summary>
        /// <typeparam name="T">要写入的数据类型</typeparam>
        /// <param name="stream">要写入的流</param>
        /// <param name="iDataBuffer">I数据buffer</param>
        /// <param name="qDataBuffer">Q数据buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型,为null时与buffer数据类型一致</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        /// <exception cref="ArgumentException">数据流不可写异常</exception>
        public static void WriteIQ<T>(Stream stream, T[] iDataBuffer, T[] qDataBuffer, int startIndex = -1,
            int count = -1, TypeCode? dataTypeCode = null)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanWrite)
            {
                throw new ArgumentException("i数据流不可写", nameof(stream));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            var writer = new BinaryWriter(stream);
            if (!dataTypeCode.HasValue)
            {
                dataTypeCode = Type.GetTypeCode(typeof(T));
            }

            PrimitiveWriteIQ<T>(writer, iDataBuffer, qDataBuffer, startIndex, count, dataTypeCode.Value);
        }

        /// <summary>
        /// 将IQ数据写到BinaryWriter
        /// </summary>
        /// <typeparam name="T">要写入的数据类型</typeparam>
        /// <param name="writer">数据BinaryWriter</param>
        /// <param name="iDataBuffer">I数据buffer</param>
        /// <param name="qDataBuffer">Q数据buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型,为null时与buffer数据类型一致</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        /// <exception cref="ArgumentException">数据流不可写异常</exception>
        public static void WriteIQ<T>(BinaryWriter writer, T[] iDataBuffer, T[] qDataBuffer, int startIndex = -1,
            int count = -1, TypeCode? dataTypeCode = null)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (!writer.BaseStream.CanWrite)
            {
                throw new ArgumentException("i数据流不可写", nameof(writer));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            if (!dataTypeCode.HasValue)
            {
                dataTypeCode = Type.GetTypeCode(typeof(T));
            }

            PrimitiveWriteIQ<T>(writer, iDataBuffer, qDataBuffer, startIndex, count, dataTypeCode.Value);
        }



        private static void PrimitiveWriteIQ(BinaryWriter writer, Complex[] buffer, int startIndex, int count, TypeCode dataTypeCode)
        {
            int endIndex = EnumerableEx.CheckCollectionPartRangePara(buffer.Length, ref startIndex, ref count);

            switch (dataTypeCode)
            {
                case TypeCode.Char:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((char)buffer[i].Real);
                        writer.Write((char)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Byte:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((byte)buffer[i].Real);
                        writer.Write((byte)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.SByte:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((sbyte)buffer[i].Real);
                        writer.Write((sbyte)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Int16:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((Int16)buffer[i].Real);
                        writer.Write((Int16)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.UInt16:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((UInt16)buffer[i].Real);
                        writer.Write((UInt16)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Int32:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((Int32)buffer[i].Real);
                        writer.Write((Int32)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.UInt32:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((UInt32)buffer[i].Real);
                        writer.Write((UInt32)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Int64:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((Int64)buffer[i].Real);
                        writer.Write((Int64)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.UInt64:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((UInt64)buffer[i].Real);
                        writer.Write((UInt64)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Single:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((float)buffer[i].Real);
                        writer.Write((float)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Double:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((double)buffer[i].Real);
                        writer.Write((double)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Decimal:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        writer.Write((decimal)buffer[i].Real);
                        writer.Write((decimal)buffer[i].Imaginary);
                    }
                    break;
                default:
                    throw new NotImplementedException($"未实现的目标数据类型{dataTypeCode.ToString()}");
            }
        }

        /// <summary>
        /// 将Complex数据写到文件
        /// </summary>
        /// <param name="filePath">IQ数据文件路径</param>
        /// <param name="buffer">复数buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="fileMode">文件打开操作模式</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        public static void WriteIQ(string filePath, Complex[] buffer, int startIndex = -1, int count = -1,
            FileMode fileMode = FileMode.CreateNew, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (string.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentNullException(nameof(filePath));
            }
            else
            {
                DirectoryInfoEx.CheckFilePathDirectory(filePath);
            }

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            using (var fs = new FileStream(filePath, fileMode, FileAccess.Write))
            {
                var writer = new BinaryWriter(fs);
                PrimitiveWriteIQ(writer, buffer, startIndex, count, dataTypeCode);
            }
        }

        /// <summary>
        /// 将Complex数据写到两个Stream
        /// </summary>
        /// <param name="stream">数据Stream</param>
        /// <param name="buffer">复数buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        /// <exception cref="ArgumentException">数据流不可写异常</exception>
        public static void WriteIQ(Stream stream, Complex[] buffer, int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanWrite)
            {
                throw new ArgumentException("数据流不可写", nameof(stream));
            }

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            var writer = new BinaryWriter(stream);
            PrimitiveWriteIQ(writer, buffer, startIndex, count, dataTypeCode);
        }

        /// <summary>
        /// 将Complex数据写到BinaryWriter
        /// </summary>
        /// <param name="writer">数据BinaryWriter</param>
        /// <param name="buffer">复数buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        /// <exception cref="ArgumentException">数据流不可写异常</exception>
        public static void WriteIQ(BinaryWriter writer, Complex[] buffer, int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (!writer.BaseStream.CanWrite)
            {
                throw new ArgumentException("数据流不可写", nameof(writer));
            }

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }


            PrimitiveWriteIQ(writer, buffer, startIndex, count, dataTypeCode);
        }



        private static void PrimitiveWriteIQ<T>(BinaryWriter iDataWriter, BinaryWriter qDataWriter,
            T[] iDataBuffer, T[] qDataBuffer, int startIndex, int count, TypeCode dataTypeCode)
        {
            int maxLength = iDataBuffer.Length < qDataBuffer.Length ? iDataBuffer.Length : qDataBuffer.Length;
            int endIndex = EnumerableEx.CheckCollectionPartRangePara(maxLength, ref startIndex, ref count);

            switch (dataTypeCode)
            {
                case TypeCode.Char:
                    var charIBuffer = iDataBuffer as char[];
                    var charQBuffer = qDataBuffer as char[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(charIBuffer[i]);
                        qDataWriter.Write(charQBuffer[i]);
                    }
                    break;
                case TypeCode.Byte:
                    var byteIBuffer = iDataBuffer as byte[];
                    var byteQBuffer = qDataBuffer as byte[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(byteIBuffer[i]);
                        qDataWriter.Write(byteQBuffer[i]);
                    }
                    break;
                case TypeCode.SByte:
                    var sByteIBuffer = iDataBuffer as sbyte[];
                    var sByteQBuffer = qDataBuffer as sbyte[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(sByteIBuffer[i]);
                        qDataWriter.Write(sByteQBuffer[i]);
                    }
                    break;
                case TypeCode.Int16:
                    var int16IBuffer = iDataBuffer as Int16[];
                    var int16QBuffer = qDataBuffer as Int16[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(int16IBuffer[i]);
                        qDataWriter.Write(int16QBuffer[i]);
                    }
                    break;
                case TypeCode.UInt16:
                    var uInt16IBuffer = iDataBuffer as UInt16[];
                    var uInt16QBuffer = qDataBuffer as UInt16[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(uInt16IBuffer[i]);
                        qDataWriter.Write(uInt16QBuffer[i]);
                    }
                    break;
                case TypeCode.Int32:
                    var int32IBuffer = iDataBuffer as Int32[];
                    var int32QBuffer = qDataBuffer as Int32[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(int32IBuffer[i]);
                        qDataWriter.Write(int32QBuffer[i]);
                    }
                    break;
                case TypeCode.UInt32:
                    var uInt32IBuffer = iDataBuffer as UInt32[];
                    var uInt32QBuffer = qDataBuffer as UInt32[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(uInt32IBuffer[i]);
                        qDataWriter.Write(uInt32QBuffer[i]);
                    }
                    break;
                case TypeCode.Int64:
                    var int64IBuffer = iDataBuffer as Int64[];
                    var int64QBuffer = qDataBuffer as Int64[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(int64IBuffer[i]);
                        qDataWriter.Write(int64QBuffer[i]);
                    }
                    break;
                case TypeCode.UInt64:
                    var uInt64IBuffer = iDataBuffer as UInt64[];
                    var uInt64QBuffer = qDataBuffer as UInt64[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(uInt64IBuffer[i]);
                        qDataWriter.Write(uInt64QBuffer[i]);
                    }
                    break;
                case TypeCode.Single:
                    var floatIBuffer = iDataBuffer as float[];
                    var floatQBuffer = qDataBuffer as float[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(floatIBuffer[i]);
                        qDataWriter.Write(floatQBuffer[i]);
                    }
                    break;
                case TypeCode.Double:
                    var doubleIBuffer = iDataBuffer as double[];
                    var doubleQBuffer = qDataBuffer as double[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(doubleIBuffer[i]);
                        qDataWriter.Write(doubleQBuffer[i]);
                    }
                    break;
                case TypeCode.Decimal:
                    var decimalIBuffer = iDataBuffer as decimal[];
                    var decimalQBuffer = qDataBuffer as decimal[];
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write(decimalIBuffer[i]);
                        qDataWriter.Write(decimalQBuffer[i]);
                    }
                    break;
                default:
                    throw new NotImplementedException($"未实现的目标数据类型{dataTypeCode.ToString()}");
            }
        }

        /// <summary>
        /// 将IQ数据写到两个文件
        /// </summary>
        /// <typeparam name="T">要写入的数据类型</typeparam>
        /// <param name="iDataFilePath">I数据文件路径</param>
        /// <param name="qDataFilePath">Q数据文件路径</param>
        /// <param name="iDataBuffer">I数据buffer</param>
        /// <param name="qDataBuffer">Q数据buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="fileMode">文件打开操作模式</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型,为null时与buffer数据类型一致</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        public static void WriteIQ<T>(string iDataFilePath, string qDataFilePath, T[] iDataBuffer, T[] qDataBuffer,
            int startIndex = -1, int count = -1, FileMode fileMode = FileMode.CreateNew, TypeCode? dataTypeCode = null)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (string.IsNullOrWhiteSpace(qDataFilePath))
            {
                throw new ArgumentNullException(nameof(qDataFilePath));
            }
            else
            {
                DirectoryInfoEx.CheckFilePathDirectory(iDataFilePath);
            }

            if (string.IsNullOrWhiteSpace(qDataFilePath))
            {
                throw new ArgumentNullException(nameof(qDataFilePath));
            }
            else
            {
                DirectoryInfoEx.CheckFilePathDirectory(qDataFilePath);
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            using (var fsI = new FileStream(iDataFilePath, fileMode, FileAccess.Write))
            {
                using (var fsQ = new FileStream(qDataFilePath, fileMode, FileAccess.Write))
                {
                    var iDataWriter = new BinaryWriter(fsI);
                    var qDataWriter = new BinaryWriter(fsQ);
                    if (!dataTypeCode.HasValue)
                    {
                        dataTypeCode = Type.GetTypeCode(typeof(T));
                    }

                    PrimitiveWriteIQ(iDataWriter, qDataWriter, iDataBuffer, qDataBuffer, startIndex, count, dataTypeCode.Value);
                }
            }
        }

        /// <summary>
        /// 将IQ数据写到两个Stream
        /// </summary>
        /// <typeparam name="T">要写入的数据类型</typeparam>
        /// <param name="iDataStream">I数据Stream</param>
        /// <param name="qDataStream">Q数据Stream</param>
        /// <param name="iDataBuffer">I数据buffer</param>
        /// <param name="qDataBuffer">Q数据buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型,为null时与buffer数据类型一致</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        /// <exception cref="ArgumentException">数据流不可写异常</exception>
        public static void WriteIQ<T>(Stream iDataStream, Stream qDataStream, T[] iDataBuffer, T[] qDataBuffer,
            int startIndex = -1, int count = -1, TypeCode? dataTypeCode = null)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (iDataStream == null)
            {
                throw new ArgumentNullException(nameof(iDataStream));
            }

            if (qDataStream == null)
            {
                throw new ArgumentNullException(nameof(qDataStream));
            }

            if (!iDataStream.CanWrite)
            {
                throw new ArgumentException("i数据流不可写", nameof(iDataStream));
            }

            if (!qDataStream.CanWrite)
            {
                throw new ArgumentException("q数据流不可写", nameof(qDataStream));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            var iDataWriter = new BinaryWriter(iDataStream);
            var qDataWriter = new BinaryWriter(qDataStream);
            if (!dataTypeCode.HasValue)
            {
                dataTypeCode = Type.GetTypeCode(typeof(T));
            }

            PrimitiveWriteIQ(iDataWriter, qDataWriter, iDataBuffer, qDataBuffer, startIndex, count, dataTypeCode.Value);
        }

        /// <summary>
        /// 将IQ数据写到两个BinaryWriter
        /// </summary>
        /// <typeparam name="T">要写入的数据类型</typeparam>
        /// <param name="iDataWriter">I数据BinaryWriter</param>
        /// <param name="qDataWriter">Q数据BinaryWriter</param>
        /// <param name="iDataBuffer">I数据buffer</param>
        /// <param name="qDataBuffer">Q数据buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型,为null时与buffer数据类型一致</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        /// <exception cref="ArgumentException">数据流不可写异常</exception>
        public static void WriteIQ<T>(BinaryWriter iDataWriter, BinaryWriter qDataWriter, T[] iDataBuffer, T[] qDataBuffer,
            int startIndex = -1, int count = -1, TypeCode? dataTypeCode = null)
            where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>
        {
            if (iDataWriter == null)
            {
                throw new ArgumentNullException(nameof(iDataWriter));
            }

            if (qDataWriter == null)
            {
                throw new ArgumentNullException(nameof(qDataWriter));
            }

            if (!iDataWriter.BaseStream.CanWrite)
            {
                throw new ArgumentException("i数据流不可写", nameof(iDataWriter));
            }

            if (!qDataWriter.BaseStream.CanWrite)
            {
                throw new ArgumentException("q数据流不可写", nameof(qDataWriter));
            }

            if (iDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(iDataBuffer));
            }

            if (qDataBuffer == null)
            {
                throw new ArgumentNullException(nameof(qDataBuffer));
            }

            if (!dataTypeCode.HasValue)
            {
                dataTypeCode = Type.GetTypeCode(typeof(T));
            }

            PrimitiveWriteIQ(iDataWriter, qDataWriter, iDataBuffer, qDataBuffer, startIndex, count, dataTypeCode.Value);
        }



        private static void PrimitiveWriteIQ(BinaryWriter iDataWriter, BinaryWriter qDataWriter, Complex[] buffer, int startIndex, int count, TypeCode dataTypeCode)
        {
            int endIndex = EnumerableEx.CheckCollectionPartRangePara(buffer.Length, ref startIndex, ref count);

            switch (dataTypeCode)
            {
                case TypeCode.Char:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((char)buffer[i].Real);
                        qDataWriter.Write((char)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Byte:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((byte)buffer[i].Real);
                        qDataWriter.Write((byte)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.SByte:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((sbyte)buffer[i].Real);
                        qDataWriter.Write((sbyte)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Int16:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((Int16)buffer[i].Real);
                        qDataWriter.Write((Int16)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.UInt16:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((UInt16)buffer[i].Real);
                        qDataWriter.Write((UInt16)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Int32:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((Int32)buffer[i].Real);
                        qDataWriter.Write((Int32)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.UInt32:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((UInt32)buffer[i].Real);
                        qDataWriter.Write((UInt32)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Int64:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((Int64)buffer[i].Real);
                        qDataWriter.Write((Int64)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.UInt64:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((UInt64)buffer[i].Real);
                        qDataWriter.Write((UInt64)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Single:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((float)buffer[i].Real);
                        qDataWriter.Write((float)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Double:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((double)buffer[i].Real);
                        qDataWriter.Write((double)buffer[i].Imaginary);
                    }
                    break;
                case TypeCode.Decimal:
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        iDataWriter.Write((decimal)buffer[i].Real);
                        qDataWriter.Write((decimal)buffer[i].Imaginary);
                    }
                    break;
                default:
                    throw new NotImplementedException($"未实现的目标数据类型{dataTypeCode.ToString()}");
            }
        }

        /// <summary>
        /// 将Complex数据写到两个文件
        /// </summary>
        /// <param name="iDataFilePath">I数据文件路径</param>
        /// <param name="qDataFilePath">Q数据文件路径</param>
        /// <param name="buffer">复数buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="fileMode">文件打开操作模式</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        public static void WriteIQ(string iDataFilePath, string qDataFilePath, Complex[] buffer, int startIndex = -1,
            int count = -1, FileMode fileMode = FileMode.CreateNew, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (string.IsNullOrWhiteSpace(qDataFilePath))
            {
                throw new ArgumentNullException(nameof(qDataFilePath));
            }
            else
            {
                DirectoryInfoEx.CheckFilePathDirectory(iDataFilePath);
            }

            if (string.IsNullOrWhiteSpace(qDataFilePath))
            {
                throw new ArgumentNullException(nameof(qDataFilePath));
            }
            else
            {
                DirectoryInfoEx.CheckFilePathDirectory(qDataFilePath);
            }

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            using (var fsI = new FileStream(iDataFilePath, fileMode, FileAccess.Write))
            {
                using (var fsQ = new FileStream(qDataFilePath, fileMode, FileAccess.Write))
                {
                    var iDataWriter = new BinaryWriter(fsI);
                    var qDataWriter = new BinaryWriter(fsQ);
                    PrimitiveWriteIQ(iDataWriter, qDataWriter, buffer, startIndex, count, dataTypeCode);
                }
            }
        }

        /// <summary>
        /// 将Complex数据写到两个Stream
        /// </summary>
        /// <param name="iDataStream">I数据Stream</param>
        /// <param name="qDataStream">Q数据Stream</param>
        /// <param name="buffer">复数buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        /// <exception cref="ArgumentException">数据流不可写异常</exception>
        public static void WriteIQ(Stream iDataStream, Stream qDataStream, Complex[] buffer, int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (iDataStream == null)
            {
                throw new ArgumentNullException(nameof(iDataStream));
            }

            if (qDataStream == null)
            {
                throw new ArgumentNullException(nameof(qDataStream));
            }

            if (!iDataStream.CanWrite)
            {
                throw new ArgumentException("i数据流不可写", nameof(iDataStream));
            }

            if (!qDataStream.CanWrite)
            {
                throw new ArgumentException("q数据流不可写", nameof(qDataStream));
            }

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            var iDataWriter = new BinaryWriter(iDataStream);
            var qDataWriter = new BinaryWriter(qDataStream);
            PrimitiveWriteIQ(iDataWriter, qDataWriter, buffer, startIndex, count, dataTypeCode);
        }

        /// <summary>
        /// 将Complex数据写到两个BinaryWriter
        /// </summary>
        /// <param name="iDataWriter">I数据BinaryWriter</param>
        /// <param name="qDataWriter">Q数据BinaryWriter</param>
        /// <param name="buffer">复数buffer</param>
        /// <param name="startIndex">buffer中的起始位置,小于10表示从0开始</param>
        /// <param name="count">buffer中的元素个数,小于10表示到结尾</param>
        /// <param name="dataTypeCode">写到BinaryWriter中的目标数据类型</param>
        /// <exception cref="ArgumentNullException">参数空引用异常</exception>
        /// <exception cref="ArgumentException">数据流不可写异常</exception>
        public static void WriteIQ(BinaryWriter iDataWriter, BinaryWriter qDataWriter, Complex[] buffer, int startIndex = -1, int count = -1, TypeCode dataTypeCode = TypeCode.Int16)
        {
            if (iDataWriter == null)
            {
                throw new ArgumentNullException(nameof(iDataWriter));
            }

            if (qDataWriter == null)
            {
                throw new ArgumentNullException(nameof(qDataWriter));
            }

            if (!iDataWriter.BaseStream.CanWrite)
            {
                throw new ArgumentException("i数据流不可写", nameof(iDataWriter));
            }

            if (!qDataWriter.BaseStream.CanWrite)
            {
                throw new ArgumentException("q数据流不可写", nameof(qDataWriter));
            }

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            PrimitiveWriteIQ(iDataWriter, qDataWriter, buffer, startIndex, count, dataTypeCode);
        }

        #endregion

    }
}
